import { useCache, type CacheParams } from '../utils/useCache'
/**
 * 在 fetch 中添加接口缓存机制
 */

const _fetch = (url: string, options: any) => {
    return fetch(url, options).then((res) => res.json())
}

export const handlerRequest = (
    url: string,
    method: string,
    params: { [key: string]: any },
    options: { cache?: CacheParams; headers?: { [key: string]: any } }
) => {
    // 获取缓存数据 - start -
    const getCacheData = useCache({ url, method, params })
    const data = getCacheData(options.cache ?? false)
    if (data) {
        return Promise.resolve(data)
    }
    // 获取缓存数据 - end -

    // 处理 fetch 配置参数
    const { headers = {} } = options
    const _options: { [key: string]: any } = {
        method,
        headers
    }
    if (method === 'GET' || method === 'DELETE') {
        const queryString = new URLSearchParams(params).toString()
        url = `${url}?${queryString}`
    } else {
        _options.body = JSON.stringify(params)
        if (!headers['Content-Type']) {
            headers['Content-Type'] = 'application/json'
        }
    }
    return _fetch(url, _options)
        .then((data) => {
            // 设置缓存数据 - start -
            const setCacheData = useCache({ url, method, params, data })
            setCacheData(options.cache ?? false)
            // 设置缓存数据 - end -
            return data
        })
        .catch((err) => console.log(err))
}

export const _get = (url: string, params: object = {}, options = {}): any => {
    return handlerRequest(url, 'GET', params, options)
}

export const _post = (url: string, params: object = {}, options = {}): any => {
    return handlerRequest(url, 'POST', params, options)
}

export const _put = (url: string, params: object = {}, options = {}): any => {
    return handlerRequest(url, 'PUT', params, options)
}

export const _del = (url: string, params: object = {}, options = {}): any => {
    return handlerRequest(url, 'DELETE', params, options)
}

/**
 * fetch 仅可以获取本地的数据
 * 修改不了本地数据，这个方法只能修改服务的数据
 * getNativeData 有效
 * setNativeData 在本地无效
 */
export const getNativeData = (fileName: string): any => {
    const url = '@/mock/database/' + fileName + '.json'
    return fetch(url)
        .then((res) => res.json())
        .then((data) => data)
        .catch((err) => console.log(err))
}

export const setNativeData = (fileName: string, jsonData: Object): any => {
    const url = '@/mock/database//' + fileName + '.json'
    return fetch(url, {
        method: 'PUT',
        body: JSON.stringify(jsonData)
    })
        .then((res) => res.json())
        .then((data) => data)
        .catch((err) => console.log(err))
}
